home *** CD-ROM | disk | FTP | other *** search
- /* Test a Mach thread_state for being in a mach_msg syscall. i386 version.
- Copyright (C) 1994 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc., 675 Mass Ave,
- Cambridge, MA 02139, USA. */
-
- #include <hurd/signal.h>
- #include <mach/thread_status.h>
- #include <string.h>
- #include <setjmp.h>
-
- extern jmp_buf _hurd_sigthread_fault_env;
-
- /* Return nonzero if STATE indicates a thread
- that is blocked in a mach_msg system call. */
- int
- _hurd_thread_state_msging_p (void *state, mach_port_t *port)
- {
- if (setjmp (_hurd_sigthread_fault_env))
- /* The PC or SP pointed at bogus memory. */
- return 0;
- else
- {
- struct i386_thread_state *ts = state;
- const unsigned char *pc = (void *) ts->eip;
- static const unsigned char lcall[] = { 0x9a, 0, 0, 0, 0, 7, 0 };
- if (ts->eax == -25 && /* mach_msg_trap XXX */
- !memcmp (pc - sizeof (lcall), lcall, sizeof (lcall)))
- {
- /* We are blocked in a mach_msg_trap system call.
- Examine the parameters to find the receive right. */
- struct mach_msg_trap_args
- {
- /* This is the order of arguments to mach_msg_trap. */
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t timeout;
- mach_port_t notify;
- } *args;
- /* The arguments begin after one word at the top of stack
- that is the address mach_msg_trap will return to. */
- args = (void *) &((int **) ts->uesp)[1];
- /* Now ARGS points just past the end of the arguments;
- decrement it to point at the beginning of the arguments. */
- --args;
- *port = args->rcv_name;
- return 1;
- }
- return 0;
- }
- }
-